package com.ruoyi.datastatistics.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import com.ruoyi.basedata.domain.TerminalsDb;
import com.ruoyi.basedata.domain.TerminalsXb;
import com.ruoyi.basedata.mapper.TerminalsDbMapper;
import com.ruoyi.basedata.service.ITerminalsXbService;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.datastatistics.domain.MeterHistoryData;
import com.ruoyi.datastatistics.domain.Realtimegatherdata;
import com.ruoyi.datastatistics.domain.RealtimegatherdataXb;
import com.ruoyi.datastatistics.domain.TerminalHistoryData;
import com.ruoyi.datastatistics.domain.recvdata.RecvDataDb;
import com.ruoyi.datastatistics.mapper.*;
import com.ruoyi.basedata.mapper.TerminalsXbMapper;
import com.ruoyi.datastatistics.service.IRealtimegatherdataXbService;
import com.ruoyi.datastatistics.service.RecvDataService;
import com.ruoyi.datastatistics.domain.recvdata.RecvData;
import com.ruoyi.datastatistics.domain.recvdata.RecvDataXb;
import com.ruoyi.system.service.ISysDictDataService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @author zhangjie
 */
@Service
public class RecvDataServiceImpl implements RecvDataService {
    private static final Logger log = LoggerFactory.getLogger(RecvDataServiceImpl.class);


    private final RecvDataMapper recvDataMapper;

    private final RealtimegatherdataXbMapper realtimegatherdataXbMapper;



    private final TerminalsXbMapper terminalsXbMapper;

    private final MeterHistoryDataMapper meterHistoryDataMapper;

    private final RealtimegatherdataMapper realtimegatherdataMapper;

    private final TerminalsDbMapper terminalsDbMapper;

    private final TerminalHistoryDataMapper terminalHistoryDataMapper;

    @Autowired
    private ITerminalsXbService terminalsXbService;

    @Autowired
    private IRealtimegatherdataXbService realtimegatherdataXbService;


    @Autowired
    ISysDictDataService iSysDictDataService;



    public RecvDataServiceImpl(RecvDataMapper recvDataMapper, RealtimegatherdataXbMapper realtimegatherdataXbMapper, TerminalsXbMapper terminalsXbMapper, MeterHistoryDataMapper meterHistoryDataMapper, RealtimegatherdataMapper realtimegatherdataMapper, TerminalsDbMapper terminalsDbMapper, TerminalHistoryDataMapper terminalHistoryDataMapper) {
        this.recvDataMapper = recvDataMapper;
        this.realtimegatherdataXbMapper = realtimegatherdataXbMapper;
        this.terminalsXbMapper = terminalsXbMapper;
        this.meterHistoryDataMapper = meterHistoryDataMapper;
        this.realtimegatherdataMapper = realtimegatherdataMapper;
        this.terminalsDbMapper = terminalsDbMapper;
        this.terminalHistoryDataMapper = terminalHistoryDataMapper;
    }

    /**
     * 把接收到的数据存入中间库
     *
     * @param recvData 接收到的数据
     * @return 是否成功
     */
    @Override
    public boolean saveRecvData(RecvData recvData) {
        return recvDataMapper.insertRecvData(recvData) > 0;
    }

    /**
     * 把接收到的数据存入中间库
     *
     * @param recvData 接收到的数据
     * @return 是否成功
     */
    @Override
    public boolean saveRecvDataXb(RecvDataXb recvData) {
        return recvDataMapper.batchInsertOrUpdateRecvDataXb(recvData) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveRecvDataXbBatch(List<RecvDataXb> recvDataList) {
        if(recvDataList.isEmpty()){
            return true;
        }
        List<TerminalsXb>  terminalsXbList = terminalsXbService.list();
        List<RecvDataXb.XbData>  xbDataListHis = new ArrayList<>();
        List<RealtimegatherdataXb>  realtimegatherdataXbList = new ArrayList<>();
        for (RecvDataXb recvDataXb : recvDataList){
            if(ObjectUtils.isNotEmpty(recvDataXb.getRealtimeData())){
                RealtimegatherdataXb realtimegatherdataXb = getRealtimegatherdataXb(recvDataXb , terminalsXbList);
                if(ObjectUtils.isNotEmpty(realtimegatherdataXb)){
                    realtimegatherdataXbList.add(realtimegatherdataXb);
                }
            }
            if (ObjectUtils.isNotEmpty(recvDataXb.getHistoryData())){
                List<RecvDataXb.XbData> historyData = recvDataXb.getHistoryData();
                historyData.forEach(xbData -> xbData.setSupplierId(recvDataXb.getManufacturer()));
                xbDataListHis.addAll(historyData);
            }
        }

        RealtimegatherdataXb realtimegatherdataXb = new RealtimegatherdataXb();
        realtimegatherdataXb.setTenantId(recvDataList.get(0).getClientId());
        List<RealtimegatherdataXb> listPrev = realtimegatherdataXbService
                .selectListAll(realtimegatherdataXb);
        //默认第一次初始化  实施使用
        if(CollectionUtils.isEmpty(listPrev)){
            xbDataListHis.stream().forEach(e->e.setTotalFlowS(e.getTotalFlow()));
            realtimegatherdataXbList.stream().forEach(e->e.setTotalFlowS(e.getTotalFlow()));
        }else{


        // 处理满转状态数据
        SysDictData sysDictData  =  new SysDictData();
        sysDictData.setStatus("0");
        List<SysDictData> sysDictDataList =  iSysDictDataService.selectDictDataList(sysDictData);
        List<SysDictData> moduleTypeList =  sysDictDataList.stream().filter(e->e.getDictType().equals("module_type")).collect(Collectors.toList());
        Optional<SysDictData>  dayMaxQuantityElectricityOp =  sysDictDataList.stream().filter(e->e.getDictType()
                .equals("day_max_quantity_water")).findFirst();
        Optional<SysDictData>  dayReversalNumElectricityOp =  sysDictDataList.stream().filter(e->e.getDictType()
                .equals("day_reversal_num_water")).findFirst();

        BigDecimal RNum = dayMaxQuantityElectricityOp.isPresent()?new BigDecimal(dayMaxQuantityElectricityOp.get().getDictValue())
                :new BigDecimal("500");
        BigDecimal  reversalNum = dayReversalNumElectricityOp.isPresent()?new BigDecimal(dayReversalNumElectricityOp.get().getDictValue())
                :new BigDecimal("5");

        if(CollectionUtils.isEmpty(listPrev)){
            log.error("【千宝通】数据库前一天无数据！");
            return false;
        }
        for (RecvDataXb.XbData xbData : xbDataListHis){
            Optional<RealtimegatherdataXb>  optional = listPrev.stream().filter(item -> item.getTerminalId()
                    .equals(xbData.getTerminalId())).findFirst();
            if(!optional.isPresent()){
                log.error("【德高】数据库无该终端数据！getTerminalId:"
                        + xbData.getTerminalId());
                continue;
            }
            Optional<TerminalsXb>  optionalXb = terminalsXbList.stream().filter(item -> item.getTerminalId()
                    .equals(xbData.getTerminalId())).findFirst();
            if(!optionalXb.isPresent()){
                log.error("【德高】数据库无该终端xb！getTerminalId:"
                        + xbData.getTerminalId());
                continue;
            }
            RealtimegatherdataXb meterHistoryDataPrev = optional.get();
            TerminalsXb terminalsXb = optionalXb.get();

            //start
            Optional<SysDictData> typeOp =   moduleTypeList.stream().filter(e->e.getDictValue().
                            equals(terminalsXb.getTypeId()))
                    .findFirst();
            BigDecimal  lc = typeOp.isPresent()?new BigDecimal(typeOp.get().getRemark()):new BigDecimal("10000");

            if(ObjectUtils.isEmpty(xbData.getTotalFlow()) ||  ObjectUtils.isEmpty(meterHistoryDataPrev.getTotalFlowS())){
                setHistoryData(xbData, terminalsXb, lc);
                continue;
            }
            if((xbData.getTotalFlow().compareTo(lc)  > 0 )
                    ||   (// 与上次读数差大于R值
                    xbData.getTotalFlow().subtract(meterHistoryDataPrev.getTotalFlowS()).abs().compareTo(RNum) > 0
                            &&  //突变情况  突变满转
                            //当前读数-上次读数<0 (该值在数据字典里设置，作为叶轮倒转的误差值)$t<|当前读数-上次读数|
                            // 上次读数>当前读数  &&  非倒转:  上次读数-当前读数 > 叶轮倒转的数值
                            !( meterHistoryDataPrev.getTotalFlowS().compareTo(xbData.getTotalFlow()) > 0
                                    &&
                                meterHistoryDataPrev.getTotalFlowS().subtract(xbData.getTotalFlow()).compareTo(reversalNum) > 0
                            )
            )
            ){
                setHistoryData(xbData, terminalsXb, lc);

            }else{ //  满转计算
                if(( meterHistoryDataPrev.getTotalFlowS().compareTo(
                        xbData.getTotalFlow()) > 0
                        &&
                        meterHistoryDataPrev.getTotalFlowS().subtract(
                                xbData.getTotalFlow()).compareTo(reversalNum) > 0
                )){
                    BigDecimal  cyclesNum = ObjectUtils.isEmpty(terminalsXb.getCyclesNum())? BigDecimal.ZERO
                            : new BigDecimal(terminalsXb.getCyclesNum());
                    terminalsXb.setCyclesNum(cyclesNum.add(BigDecimal.ONE).intValue());
                    boolean isSuccess = terminalsXbService.updateById(terminalsXb);
                    if(!isSuccess){
                        throw   new RuntimeException("更新失败");
                    }
                }
                setHistoryData(xbData, terminalsXb, lc);
            }
            Optional<RealtimegatherdataXb>  realtimegatherdataXbOp = realtimegatherdataXbList.stream().
                    filter(e->e.getTerminalId().equals(xbData.getTerminalId())).findFirst();
            if(realtimegatherdataXbOp.isPresent()){
                realtimegatherdataXbOp.get().setTotalFlow(xbData.getTotalFlow());
                realtimegatherdataXbOp.get().setTotalFlowS(xbData.getTotalFlowS());
            }
        }


        }

        //TODO   read_date 排查是不是不对  赋值的时候
        // 插入历史表
        doDataXbHis(xbDataListHis);
        //插入实时表
        doRealtimedataXb(realtimegatherdataXbList);
        return true;
    }

    /**
     * TotalFlowS  无数据 需要赋值
     * @param xbData
     * @param electricityTerminalsXb
     * @param lc
     */
    private void setHistoryData(RecvDataXb.XbData xbData, TerminalsXb electricityTerminalsXb, BigDecimal lc) {
        // private void setHistoryData(ElectricityMeterHistoryData electricityMeterHistoryData, ElectricityTerminalsXb electricityTerminalsXb, BigDecimal lc) {
        if(ObjectUtils.isEmpty(xbData.getTotalFlow())){
            return;
        }
        xbData.setTotalFlowS(xbData.getTotalFlow());
        BigDecimal positiveActiveEnergyS = xbData.getTotalFlowS();
        BigDecimal  cyclesNum = ObjectUtils.isEmpty(electricityTerminalsXb.getCyclesNum())? BigDecimal.ZERO
                : new BigDecimal(electricityTerminalsXb.getCyclesNum());
        //设置展示读数
        xbData.setTotalFlow(cyclesNum.multiply(lc).add(positiveActiveEnergyS));
        // iElectricityMeterHistoryDataService.insertMeterHistoryData(electricityMeterHistoryData);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveRecvDataXbBatchCopy(List<RecvDataXb> recvDataList) {
        if(recvDataList.isEmpty()){
            return true;
        }
        List<TerminalsXb>  terminalsXbList = terminalsXbService.list();
        List<RecvDataXb.XbData>  xbDataListHis = new ArrayList<>();
        List<RealtimegatherdataXb>  realtimegatherdataXbList = new ArrayList<>();
        for (RecvDataXb recvDataXb : recvDataList){
            if(ObjectUtils.isNotEmpty(recvDataXb.getRealtimeData())){
                RealtimegatherdataXb realtimegatherdataXb = getRealtimegatherdataXbCopy(recvDataXb , terminalsXbList);
                if(ObjectUtils.isNotEmpty(realtimegatherdataXb)){
                    realtimegatherdataXbList.add(realtimegatherdataXb);
                }
            }
            if (ObjectUtils.isNotEmpty(recvDataXb.getHistoryData())){
                List<RecvDataXb.XbData> historyData = recvDataXb.getHistoryData();
                historyData.forEach(xbData -> xbData.setSupplierId(recvDataXb.getManufacturer()));
                xbDataListHis.addAll(historyData);
            }
        }

        //TODO  处理满转状态数据
        //
        // 插入历史表
        doDataXbHisCopy(xbDataListHis);
        //插入实时表
        doRealtimedataXbCopy(realtimegatherdataXbList);
        return true;
    }


    private void doDataXbHis(List<RecvDataXb.XbData> xbDataListHis) {
        if(CollectionUtils.isNotEmpty(xbDataListHis)){
            List<TerminalsXb>  terminalsXbList = terminalsXbService.list();
            for (RecvDataXb.XbData xbData : xbDataListHis){
                Optional<TerminalsXb> optionalTerminalsXb = terminalsXbList.stream().filter(e->e.getTerminalId()
                        .equals(xbData.getTerminalId())).findFirst();
                if(optionalTerminalsXb.isPresent()){
                    TerminalsXb terminalsXb = optionalTerminalsXb.get();
                    xbData.setLocationNb(terminalsXb.getLocationNb());
                }
            }
            boolean successHis =  recvDataMapper.batchInsertOrUpdateXbDataListFullNew(xbDataListHis) > 0;
            if(!successHis){
                throw  new RuntimeException("插入历史表失败");
            }
        }
    }
    private void doDataXbHisCopy(List<RecvDataXb.XbData> xbDataListHis) {
        if(CollectionUtils.isNotEmpty(xbDataListHis)){
            List<TerminalsXb>  terminalsXbList = terminalsXbService.list();
            for (RecvDataXb.XbData xbData : xbDataListHis){
                Optional<TerminalsXb> optionalTerminalsXb = terminalsXbList.stream().filter(e->e.getTerminalId()
                        .equals(xbData.getTerminalId())).findFirst();
                if(optionalTerminalsXb.isPresent()){
                    TerminalsXb terminalsXb = optionalTerminalsXb.get();
                    xbData.setLocationNb(terminalsXb.getLocationNb());
                }
            }
            boolean successHis =  recvDataMapper.batchInsertOrUpdateXbDataListFull(xbDataListHis) > 0;
            if(!successHis){
                throw  new RuntimeException("插入历史表失败");
            }
        }
    }

    private void doRealtimedataXb(List<RealtimegatherdataXb> realtimegatherdataXbList) {
        if(CollectionUtils.isNotEmpty(realtimegatherdataXbList)){
            List<RealtimegatherdataXb>  realtimegatherdataXbListAdd = realtimegatherdataXbList.stream().filter(
                    e->ObjectUtils.isEmpty(e.getId())).collect(Collectors.toList());
            List<RealtimegatherdataXb>  realtimegatherdataXbListUpdate  = realtimegatherdataXbList.stream().filter(
                    e->ObjectUtils.isNotEmpty(e.getId())).collect(Collectors.toList());
            if(CollectionUtils.isNotEmpty(realtimegatherdataXbListAdd)){
                boolean successAdd =  realtimegatherdataXbService.saveBatch(realtimegatherdataXbListAdd);
                if(!successAdd){
                    throw  new RuntimeException("插入xb实时表失败！");
                }
            }
            if(CollectionUtils.isNotEmpty(realtimegatherdataXbListUpdate)){
                boolean successUpdate =  realtimegatherdataXbService.updateBatchById(realtimegatherdataXbListUpdate);
                if(!successUpdate){
                    throw  new RuntimeException("更新xb实时表失败！");
                }
            }
        }
    }

    private void doRealtimedataXbCopy(List<RealtimegatherdataXb> realtimegatherdataXbList) {
        if(CollectionUtils.isNotEmpty(realtimegatherdataXbList)){
            List<RealtimegatherdataXb>  realtimegatherdataXbListAdd = realtimegatherdataXbList.stream().filter(
                    e->ObjectUtils.isEmpty(e.getId())).collect(Collectors.toList());
            List<RealtimegatherdataXb>  realtimegatherdataXbListUpdate  = realtimegatherdataXbList.stream().filter(
                    e->ObjectUtils.isNotEmpty(e.getId())).collect(Collectors.toList());
            if(CollectionUtils.isNotEmpty(realtimegatherdataXbListAdd)){
                boolean successAdd =  realtimegatherdataXbService.saveBatch(realtimegatherdataXbListAdd);
                if(!successAdd){
                    throw  new RuntimeException("插入xb实时表失败！");
                }
            }
            if(CollectionUtils.isNotEmpty(realtimegatherdataXbListUpdate)){
                boolean successUpdate =  realtimegatherdataXbService.updateBatchById(realtimegatherdataXbListUpdate);
                if(!successUpdate){
                    throw  new RuntimeException("更新xb实时表失败！");
                }
            }
        }
    }


    private RealtimegatherdataXb getRealtimegatherdataXb(RecvDataXb recvDataXb ,List<TerminalsXb>  terminalsXbList) {
        RecvDataXb.XbData realtimeData = recvDataXb.getRealtimeData();
        RealtimegatherdataXb realtimegatherdataXb = realtimegatherdataXbMapper
                .selectRealtimeDataByTerminalIdAndTenantId(recvDataXb.getDeviceNumber(), recvDataXb.getClientId());
        if (realtimegatherdataXb == null) {
            realtimegatherdataXb = new RealtimegatherdataXb();
            realtimegatherdataXb.setTerminalId(recvDataXb.getDeviceNumber());
            realtimegatherdataXb.setTenantId(recvDataXb.getClientId());
            Optional<TerminalsXb> optionalTerminalsXb = terminalsXbList.stream().filter(e->e.getTerminalId()
                    .equals(recvDataXb.getDeviceNumber())).findFirst();
            // TerminalsXb terminalsXb = terminalsXbList.stream().filter(e->e.getTerminalId().equals(recvDataXb.getDeviceNumber())).findFirst();
            if(optionalTerminalsXb.isPresent()){
                TerminalsXb terminalsXb = optionalTerminalsXb.get();
                realtimegatherdataXb.setLocationNb(terminalsXb.getLocationNb());
            }else{
                System.out.println(String.format("未找到终端 %s 的终端信息", recvDataXb.getDeviceNumber()));
                log.error("未找到终端{}的终端信息", recvDataXb.getDeviceNumber());
                return  null;

            }
            // realtimegatherdataXb.setLocationNb(terminalsXb.getLocationNb());
            realtimegatherdataXb.setCreateTime(new Date());
        }
        realtimegatherdataXb.setTotalFlow(realtimeData.getTotalFlow());
        realtimegatherdataXb.setTerminalCsq(realtimeData.getTerminalCsq());
        realtimegatherdataXb.setTerminalVol(realtimeData.getTerminalVol());
        realtimegatherdataXb.setValveState(Convert.toBigDecimal(realtimeData.getValveState()));
        realtimegatherdataXb.setReadDate(realtimeData.getReadDate());
        return realtimegatherdataXb;
    }


    private RealtimegatherdataXb getRealtimegatherdataXbCopy(RecvDataXb recvDataXb ,List<TerminalsXb>  terminalsXbList) {
        RecvDataXb.XbData realtimeData = recvDataXb.getRealtimeData();
        RealtimegatherdataXb realtimegatherdataXb = realtimegatherdataXbMapper
                .selectRealtimeDataByTerminalIdAndTenantId(recvDataXb.getDeviceNumber(), recvDataXb.getClientId());
        if (realtimegatherdataXb == null) {
            realtimegatherdataXb = new RealtimegatherdataXb();
            realtimegatherdataXb.setTerminalId(recvDataXb.getDeviceNumber());
            realtimegatherdataXb.setTenantId(recvDataXb.getClientId());
            Optional<TerminalsXb> optionalTerminalsXb = terminalsXbList.stream().filter(e->e.getTerminalId()
                    .equals(recvDataXb.getDeviceNumber())).findFirst();
            // TerminalsXb terminalsXb = terminalsXbList.stream().filter(e->e.getTerminalId().equals(recvDataXb.getDeviceNumber())).findFirst();
            if(optionalTerminalsXb.isPresent()){
                TerminalsXb terminalsXb = optionalTerminalsXb.get();
                realtimegatherdataXb.setLocationNb(terminalsXb.getLocationNb());
            }else{
                System.out.println(String.format("未找到终端 %s 的终端信息", recvDataXb.getDeviceNumber()));
                log.error("未找到终端{}的终端信息", recvDataXb.getDeviceNumber());
                return  null;

            }
            // realtimegatherdataXb.setLocationNb(terminalsXb.getLocationNb());
            realtimegatherdataXb.setCreateTime(new Date());
        }
        realtimegatherdataXb.setTotalFlow(realtimeData.getTotalFlow());
        realtimegatherdataXb.setTerminalCsq(realtimeData.getTerminalCsq());
        realtimegatherdataXb.setTerminalVol(realtimeData.getTerminalVol());
        realtimegatherdataXb.setValveState(Convert.toBigDecimal(realtimeData.getValveState()));
        realtimegatherdataXb.setReadDate(realtimeData.getReadDate());
        return realtimegatherdataXb;
    }

    @Override
    public boolean saveRealtimeDataXb(RecvDataXb recvData) {
        RecvDataXb.XbData realtimeData = recvData.getRealtimeData();
        RealtimegatherdataXb realtimegatherdataXb = realtimegatherdataXbMapper.selectRealtimeDataByTerminalIdAndTenantId(recvData.getDeviceNumber(), recvData.getClientId());
        if (realtimegatherdataXb == null) {
            realtimegatherdataXb = new RealtimegatherdataXb();
            realtimegatherdataXb.setTerminalId(recvData.getDeviceNumber());
            realtimegatherdataXb.setTenantId(recvData.getClientId());
            TerminalsXb terminalsXb = terminalsXbMapper.selectTerminalsXbByTerminalID(recvData.getDeviceNumber());
            realtimegatherdataXb.setLocationNb(terminalsXb.getLocationNb());
            realtimegatherdataXb.setCreateTime(new Date());
        }
        realtimegatherdataXb.setTotalFlow(realtimeData.getTotalFlow());
        realtimegatherdataXb.setTerminalCsq(realtimeData.getTerminalCsq());
        realtimegatherdataXb.setTerminalVol(realtimeData.getTerminalVol());
        realtimegatherdataXb.setValveState(Convert.toBigDecimal(realtimeData.getValveState()));
        realtimegatherdataXb.setReadDate(realtimeData.getReadDate());
        boolean success;
        if (realtimegatherdataXb.getId() == null) {
            success = realtimegatherdataXbMapper.insert(realtimegatherdataXb) > 0;
        } else {
            success = realtimegatherdataXbMapper.updateById(realtimegatherdataXb) > 0;
        }
        return success;
    }

    /**
     * 保存户表历史数据
     */
    @Override
    public void saveHistoryDataXb() {
        List<RecvDataXb.XbData> xbDataList = recvDataMapper.selectRecvXbData();
        List<Long> successIds = new ArrayList<>();
        List<Long> failIds = new ArrayList<>();
        for (RecvDataXb.XbData xbData : xbDataList) {
            if (StringUtils.isBlank(xbData.getLocationNb())) {
                failIds.add(xbData.getId());
                continue;
            }
            MeterHistoryData meterHistoryData = BeanUtil.copyProperties(xbData, MeterHistoryData.class, "id");
            meterHistoryData.setReadDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, xbData.getReadDate()));
            meterHistoryData.setCreateDate(new Date());
            int rows = meterHistoryDataMapper.insert(meterHistoryData);
            if (rows > 0) {
                successIds.add(xbData.getId());
            } else {
                failIds.add(xbData.getId());
            }
        }
        String tableName = "t_recv_data_xb";
        if(CollectionUtils.isNotEmpty(successIds)){
            recvDataMapper.updateSyncStatusByIds(tableName, "2", successIds);
            }
        if(CollectionUtils.isNotEmpty(failIds)){
            recvDataMapper.updateSyncStatusByIds(tableName, "3", failIds);
        }


    }

    /**
     * 把接收到的大表数据存入中间库
     *
     * @param recvData 接收到的数据
     * @return 是否成功
     */
    @Override
    public boolean saveRecvDataDb(RecvDataDb recvData) {
        boolean success = false;
        // 保存实时数据
        RecvDataDb.DbData realtimeData = recvData.getRealtimeData();
        if (realtimeData != null) {
            success = saveRealtimeDataDb(recvData);
        }
        // 保存历史数据
        if (CollectionUtils.isNotEmpty(recvData.getHistoryData())) {
            success = success && (recvDataMapper.batchInsertOrUpdateRecvDataDb(recvData) > 0);
        }
        return success;
    }

    private boolean saveRealtimeDataDb(RecvDataDb recvData) {
        RecvDataDb.DbData realtimeData = recvData.getRealtimeData();
        Realtimegatherdata realtimegatherdata = realtimegatherdataMapper.selectRealtimegatherdataByTerminalIdAndTenantId(recvData.getDeviceNumber(), recvData.getClientId());
        if (realtimegatherdata == null) {
            realtimegatherdata = new Realtimegatherdata();
            realtimegatherdata.setTerminalId(recvData.getDeviceNumber());
            realtimegatherdata.setTenantId(recvData.getClientId());
            TerminalsDb terminalsDb = terminalsDbMapper.selectTerminalsDbByTerminalId(recvData.getDeviceNumber());
            realtimegatherdata.setLocationNb(terminalsDb.getLocationNb());
            realtimegatherdata.setCreateTime(new Date());
        }
        realtimegatherdata.setTotalFlow(realtimeData.getTotalFlow());
        realtimegatherdata.setReadNumber(realtimeData.getReadNumber());
        realtimegatherdata.setReverseNumber(realtimeData.getReverseNumber());
        realtimegatherdata.setInstantNumber(realtimeData.getInstantNumber());
        realtimegatherdata.setInstantVelocity(realtimeData.getInstantVelocity());
        realtimegatherdata.setPressure(realtimeData.getPressure());
        realtimegatherdata.setTerminalCsqDescribe(realtimeData.getTerminalCsqDescribe());
        realtimegatherdata.setTerminalCsq(Convert.toLong(realtimeData.getTerminalCsq()));
        realtimegatherdata.setTerminalVol(realtimeData.getTerminalVol());
        realtimegatherdata.setValveState(realtimeData.getValveState());
        realtimegatherdata.setReadDate(realtimeData.getReadDate());
        boolean success;
        if (realtimegatherdata.getId() == null) {
            success = realtimegatherdataMapper.insert(realtimegatherdata) > 0;
        } else {
            success = realtimegatherdataMapper.updateById(realtimegatherdata) > 0;
        }
        return success;
    }

    /**
     * 保存大表历史数据
     */
    @Override
    public void saveHistoryDataDb() {
        List<RecvDataDb.DbData> dbDataList = recvDataMapper.selectRecvDbData();
        List<Long> successIds = new ArrayList<>();
        List<Long> failIds = new ArrayList<>();
        for (RecvDataDb.DbData dbData : dbDataList) {
            if (StringUtils.isBlank(dbData.getLocationNb())) {
                failIds.add(dbData.getId());
                continue;
            }
            TerminalHistoryData terminalHistoryData = BeanUtil.copyProperties(dbData, TerminalHistoryData.class, "id");
            terminalHistoryData.setCreateTime(new Date());
            int rows = terminalHistoryDataMapper.insert(terminalHistoryData);
            if (rows > 0) {
                successIds.add(dbData.getId());
            } else {
                failIds.add(dbData.getId());
            }
        }
        String tableName = "t_recv_data_db";
        recvDataMapper.updateSyncStatusByIds(tableName, "2", successIds);
        recvDataMapper.updateSyncStatusByIds(tableName, "3", failIds);
    }

    @Override
    public void deleteRecvDataRegularly() {
        recvDataMapper.deleteRecvData();
    }
}
